﻿// ====================================
// Created By Angie.D 2010.6
// ====================================

using System;
using System.Collections.Generic;
using System.Text;

using System.Windows.Forms;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;

namespace WOWMultiPlay
{
    [XmlRootAttribute("mpButton", IsNullable = false)]
    public class mpButton
    {
        public string ButtonName { get; set; }
        public mpKeyArray mpKeyArray;
        public int Repeat;
        public mpTime RepeatInterval;
        public mpHotkey Hotkey;
        public bool KeepWindowMinimize = true;
        [XmlIgnore]
        public Button WinFormButton;
        [XmlIgnore]
        public List<Thread> SendKeysThreads = new List<Thread>();
        [XmlIgnore]
        public mpButton It { get { return this; } }

        public delegate void SendKeyArrayFinished(object sender, EventArgs e);
        public event SendKeyArrayFinished OnSendKeyArrayFinished;

        public mpButton() { }

        public mpButton(string ButtonName, mpKeyArray mpKeyArray, int Repeat, mpTime RepeatInterval)
        {
            this.ButtonName = ButtonName;
            this.mpKeyArray = mpKeyArray;
            this.Repeat = Repeat;
            this.RepeatInterval = RepeatInterval;
        }

        public void SendKeyArray(IntPtr hWnd)
        {
            Thread SendKeysThread = new Thread(delegate() { SendKeys(hWnd, mpKeyArray); });
            SendKeysThread.IsBackground = true;
            SendKeysThread.Start();

            this.SendKeysThreads.Add(SendKeysThread);
        }

        public void StopSendKeyArray()
        {
            // try catch may need to be improved.
            try
            {
                foreach (Thread thread in SendKeysThreads)
                {
                    if (thread != null && thread.ThreadState != ThreadState.Aborted)
                        thread.Abort();
                }
            }
            catch { }
        }

        private void SendKeys(IntPtr hWnd, mpKeyArray mpKeyArray)
        {
            int RepeatCount = 0;

            while (Repeat == 0 || RepeatCount < Repeat)
            {
                if (this.KeepWindowMinimize)
                {
                    SendWindowMinimize(hWnd);
                }

                mpKey[] mpKeys = mpKeyArray.TranslatedKeyArray;

                foreach (mpKey mpKey in mpKeys)
                {
                    SendKey(hWnd, mpKey);
                }

                if (Repeat != 0)
                    RepeatCount++;

                if (Repeat != 1)
                    mpTimer.Sleep(RepeatInterval);
            }

            OnSendKeyArrayFinished(this, null);
        }

        // Known issue:
        // If using Hotkey, Ctrl, Alt, Shift + ? will block app response posted message.
        // Win + ? works fine.
        private void SendKey(IntPtr hWnd, mpKey mpKey)
        {
            WindowsAPI.PostMessageA(hWnd, WindowsAPI.WM.WM_KEYDOWN, mpKey.Key, 0);

            if (mpKey.KeyPressOption == KeyPressOption.KeyDownAndUp)
            {
                mpTimer.Sleep(mpKey.KeyDownUpInterval);
                WindowsAPI.PostMessageA(hWnd, WindowsAPI.WM.WM_KEYUP, mpKey.Key, 0);
            }

            mpTimer.Sleep(mpKey.KeyPressInterval);
        }

        private void SendWindowMinimize(IntPtr hWnd)
        {
            WindowsAPI.PostMessageA(hWnd, WindowsAPI.WM.WM_SYSCOMMAND, WindowsAPI.SC.SC_MINIMIZE, 0);
        }
    }
}